using Serilog;
using SPI.AgentServer.Configuration;
using SPI.AgentServer.Services;
using SPI.AgentServer.Services.AI;
using SPI.AgentServer.Services.Metadata;
using SPI.AgentServer.Services.Tools;
using SPI.AgentServer.Services.Execution;
using SPI.AgentServer.Services.Orchestration;
using SPI.AgentServer.Services.Security;
using SPI.AgentServer.Services.DatabaseLearning;
using SPI.AgentServer.Middleware;
using FluentValidation;
using FluentValidation.AspNetCore;
using Swashbuckle.AspNetCore.Filters;

var builder = WebApplication.CreateBuilder(args);

// 【关键优化】配置线程池，防止线程耗尽导致请求卡住
System.Threading.ThreadPool.SetMinThreads(100, 100);  // 最小工作线程和IO线程各100个
System.Threading.ThreadPool.SetMaxThreads(500, 500); // 最大工作线程和IO线程各500个

// 【关键优化】配置Kestrel Socket选项，防止长时间空闲后监听器失效
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.ListenAnyIP(8215, listenOptions =>
    {
        // 启用TCP KeepAlive，防止操作系统回收空闲连接
        listenOptions.UseConnectionLogging();
        
        // Socket选项配置
        listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
    });
    
    // 配置连接限制
    serverOptions.Limits.MaxConcurrentConnections = null; // 无限制
    serverOptions.Limits.MaxConcurrentUpgradedConnections = null;
    serverOptions.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10);
    serverOptions.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(1);
});

// Configure Serilog
Log.Logger = new LoggerConfiguration()
    .ReadFrom.Configuration(builder.Configuration)
    .Enrich.FromLogContext()
    .CreateLogger();

builder.Host.UseSerilog();

// Add services to the container
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();

// Add memory cache
builder.Services.AddMemoryCache();

// Configure Swagger/OpenAPI
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
    {
        Title = "SPI Agent Server API",
        Version = "v1",
        Description = "智能自然语言查询服务 API - 支持将中文/英文自然语言转换为 SQL 查询",
        Contact = new Microsoft.OpenApi.Models.OpenApiContact
        {
            Name = "SPI Team",
            Email = "support@spi.com"
        },
        License = new Microsoft.OpenApi.Models.OpenApiLicense
        {
            Name = "内部使用",
            Url = new Uri("https://internal.spi.com")
        }
    });

    // 添加 XML 注释文档
    var xmlFile = $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    if (File.Exists(xmlPath))
    {
        options.IncludeXmlComments(xmlPath);
    }

    // 添加请求示例
    options.ExampleFilters();

    // 自定义 Schema ID 生成策略，避免冲突
    options.CustomSchemaIds(type => type.FullName?.Replace("+", ".") ?? type.Name);
    
    // 启用注解
    options.EnableAnnotations();
});

// 添加 Swagger 示例提供者
builder.Services.AddSwaggerExamplesFromAssemblyOf<Program>();

// Add FluentValidation
builder.Services.AddFluentValidationAutoValidation();
builder.Services.AddValidatorsFromAssemblyContaining<Program>();

// Configure options
builder.Services.Configure<QwenConfiguration>(builder.Configuration.GetSection("Qwen"));
builder.Services.Configure<DatabaseConfiguration>(builder.Configuration.GetSection("Database"));
builder.Services.Configure<SecurityConfiguration>(builder.Configuration.GetSection("Security"));

// Register AI Services - 根据配置选择真实或模拟客户端
var useMockLLM = builder.Configuration.GetValue<bool>("Qwen:UseMock");
var useMockDB = builder.Configuration.GetValue<bool>("Database:UseMock");

if (useMockLLM)
{
    builder.Services.AddSingleton<IQwenClient, MockQwenClient>();
    Console.WriteLine("⚠️ 使用模拟大模型客户端（无需网络访问）");
}
else
{
    // 配置 HttpClient 以支持长时间空闲后的重连
    builder.Services.AddHttpClient<IQwenClient, QwenClient>()
        .ConfigurePrimaryHttpMessageHandler(() =>
        {
            var handler = new SocketsHttpHandler
            {
                // 连接池配置：保持连接5分钟，平衡性能和资源
                PooledConnectionLifetime = TimeSpan.FromMinutes(5),
                PooledConnectionIdleTimeout = TimeSpan.FromMinutes(2),
                
                // 连接超时配置
                ConnectTimeout = TimeSpan.FromSeconds(10), // 缩短连接超时，快速失败
                
                // 允许多个并发连接
                MaxConnectionsPerServer = 10,
                
                // 响应超时
                ResponseDrainTimeout = TimeSpan.FromSeconds(5),
                
                // 自动解压缩
                AutomaticDecompression = System.Net.DecompressionMethods.All
            };
            return handler;
        });
    
    Console.WriteLine("✅ 使用真实 Qwen 大模型客户端（每次请求建立新连接，避免僵尸连接）");
}

Console.WriteLine($"📊 数据库模式: {(useMockDB ? "虚拟数据（Mock）" : "真实数据")}");

// 注册 SSH 隧道服务（根据连接模式）
var connectionMode = builder.Configuration.GetValue<string>("Qwen:ConnectionMode") ?? "direct";
Console.WriteLine($"🔌 Qwen 连接模式: {connectionMode}");

if (connectionMode.Equals("ssh", StringComparison.OrdinalIgnoreCase))
{
    var sshEnabled = builder.Configuration.GetValue<bool>("Qwen:SshTunnel:Enabled");
    if (sshEnabled)
    {
        builder.Services.AddHostedService<SshTunnelService>();
        Console.WriteLine("🚇 SSH 隧道已启用");
    }
}
else if (connectionMode.Equals("direct", StringComparison.OrdinalIgnoreCase))
{
    Console.WriteLine("⚡ 使用直连模式（推荐 Windows 环境）");
}
else if (connectionMode.Equals("local", StringComparison.OrdinalIgnoreCase))
{
    Console.WriteLine("🔄 使用本地转发模式");
}

// Register services
builder.Services.AddSingleton<IPromptManager, PromptManager>();

builder.Services.AddScoped<ISchemaRegistry, SchemaRegistry>();
builder.Services.AddScoped<ISqlParser, SqlParser>();
builder.Services.AddScoped<ISqlValidator, SqlValidator>();

// Register cache services
builder.Services.AddSingleton<SPI.AgentServer.Services.Cache.IQueryCacheService, SPI.AgentServer.Services.Cache.InMemoryQueryCacheService>();

// Register background services - 连接保活服务
builder.Services.AddHostedService<SPI.AgentServer.Services.Infrastructure.ConnectionKeepAliveService>();

// Register export services
builder.Services.AddScoped<SPI.AgentServer.Services.Export.IExportService, SPI.AgentServer.Services.Export.ExcelExportService>();

// 图表服务：可以选择 SimpleChartService（简单稳定）或 EChartsService（功能丰富）
// builder.Services.AddScoped<SPI.AgentServer.Services.Export.IChartService, SPI.AgentServer.Services.Export.SimpleChartService>();
builder.Services.AddScoped<SPI.AgentServer.Services.Export.IChartService, SPI.AgentServer.Services.Export.EChartsService>();

// 根据配置选择数据库执行器（独立于大模型配置）
if (useMockDB)
{
    builder.Services.AddScoped<IDatabaseExecutor, MockDatabaseExecutor>();
}
else
{
    builder.Services.AddScoped<IDatabaseExecutor, DatabaseExecutor>();
}

builder.Services.AddScoped<IToolExecutor, ToolExecutor>();
builder.Services.AddScoped<IQueryOrchestrator, QueryOrchestrator>();
builder.Services.AddScoped<IDatabaseSchemaLearner, DatabaseSchemaLearner>();

// Register tools
builder.Services.AddScoped<IQueryTool, ExecuteSqlTool>();
builder.Services.AddScoped<IQueryTool, DescribeTableTool>();
builder.Services.AddScoped<IQueryTool, RunPrebuiltQueryTool>();
builder.Services.AddScoped<IQueryTool, GetTimeRangeTool>();

// Register business tools - SQL-based tools
builder.Services.AddScoped<IQueryTool, GetDeviceStatsTool>();
builder.Services.AddScoped<IQueryTool, GetRecentAlarmsTool>();
builder.Services.AddScoped<IQueryTool, GetAreaStatsTool>();
builder.Services.AddScoped<IQueryTool, GetUserStatsTool>();
builder.Services.AddScoped<IQueryTool, GetDatabaseSchemaTool>();
builder.Services.AddScoped<IQueryTool, GetVisitorVehiclesTool>();
builder.Services.AddScoped<IQueryTool, GetGateRecordsTool>();

// 新增业务工具 - 设备故障类
builder.Services.AddScoped<IQueryTool, GetDeviceStatusTool>();
builder.Services.AddScoped<IQueryTool, GetAlarmStatsTool>();
builder.Services.AddScoped<IQueryTool, GetDeviceAlarmRankingTool>();

// 新增业务工具 - 人员问题类
builder.Services.AddScoped<IQueryTool, GetPersonnelAccessTool>();
builder.Services.AddScoped<IQueryTool, GetCampusStatsTool>();
builder.Services.AddScoped<IQueryTool, GetBlacklistActivityTool>();
builder.Services.AddScoped<IQueryTool, GetDepartmentEmployeeTool>();
builder.Services.AddScoped<IQueryTool, GetPersonnelInOutDetailTool>();

// 新增业务工具 - 车辆问题类
builder.Services.AddScoped<IQueryTool, GetVehicleManagementTool>();
builder.Services.AddScoped<IQueryTool, GetVehicleSpecialInfoTool>();
builder.Services.AddScoped<IQueryTool, GetVehicleStatsTool>();
builder.Services.AddScoped<IQueryTool, GetOnCampusVisitorVehiclesTool>();

// 新增业务工具 - 图书馆进出类
builder.Services.AddScoped<IQueryTool, GetLibraryAccessTool>();

var app = builder.Build();

// Configure the HTTP request pipeline
// 添加请求超时中间件（必须在其他中间件之前）
app.UseRequestTimeout();

// 启用静态文件支持（用于H5页面）
app.UseStaticFiles();

// 启用 Swagger（在所有环境中都可用，方便测试��
app.UseSwagger();
app.UseSwaggerUI(options =>
{
    options.SwaggerEndpoint("/swagger/v1/swagger.json", "SPI Agent Server API V1");
    options.RoutePrefix = "swagger"; // 将 Swagger UI 移到 /swagger 路径
    options.DocumentTitle = "SPI Agent Server API 文档";
    options.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.List);
    options.DefaultModelsExpandDepth(2);
    options.DefaultModelExpandDepth(2);
    options.DisplayRequestDuration();
    options.EnableDeepLinking();
    options.EnableFilter();
    options.ShowExtensions();
    options.EnableValidator();
    options.EnableTryItOutByDefault();
});

app.UseRouting();

app.UseHttpsRedirection();
app.UseSerilogRequestLogging();

app.UseAuthorization();

app.MapControllers();

try
{
    Log.Information("Starting SPI Agent Server");
    app.Run();
}
catch (Exception ex)
{
    Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();
}
